package org.fm.demo.dao;

import cn.org.atool.fluent.mybatis.base.mapper.IEntityMapper;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.fm.demo.shared.mapper.StudentMapper;

import javax.sql.DataSource;
import java.util.function.Consumer;

public class AppSessionFactory {
    public static final AppSessionFactory sessionFactory = new AppSessionFactory();

    private SqlSessionFactory sqlSessionFactory;

    private AppSessionFactory() {
    }

    public static <M extends IEntityMapper> void execute(Class<M> klass, Consumer<M> consumer) {
        try (SqlSession sqlSession = sessionFactory.openSession()) {
            M mapper = sqlSession.getMapper(klass);
            consumer.accept(mapper);
        }
    }

    public SqlSession openSession() {
        if (sqlSessionFactory != null) {
            return sqlSessionFactory.openSession();
        }
        synchronized (AppSessionFactory.class) {
            if (sqlSessionFactory != null) {
                return sqlSessionFactory.openSession();
            }
            DataSource dataSource = this.dataSource();
            TransactionFactory transactionFactory = new JdbcTransactionFactory();
            Environment environment = new Environment("development", transactionFactory, dataSource);
            Configuration configuration = new Configuration(environment);
            configuration.addMapper(StudentMapper.class);
            this.sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
            return this.sqlSessionFactory.openSession();
        }
    }

    private DataSource dataSource() {
        String url = "jdbc:mysql://localhost:3306/fluent_mybatis?useUnicode=true&characterEncoding=utf8";
        String driver = "com.mysql.cj.jdbc.Driver";
        String username = "root";
        String password = "password";
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}